package com.taoym.voucher.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.taoym.voucher.admin.domain.SysUser;
import com.taoym.voucher.admin.entity.dto.SysUpdateUserDTO;
import com.taoym.voucher.admin.entity.dto.SysUserLoginDTO;
import com.taoym.voucher.admin.entity.dto.SysUserRefreshTokenDTO;
import com.taoym.voucher.admin.entity.vo.SysGetUserDetailVO;
import com.taoym.voucher.admin.entity.vo.SysUserLoginVO;
import com.taoym.voucher.admin.mapper.SysUserMapper;
import com.taoym.voucher.admin.service.SysUserService;
import com.taoym.voucher.admin.utils.AdminThreadLocalUtils;
import com.taoym.voucher.common.constant.RedisKeyConstant;
import com.taoym.voucher.common.response.ResponseStatusCode;
import com.taoym.voucher.common.utils.ExceptionCore;
import com.taoym.voucher.common.utils.JwtTokenUtils;
import com.taoym.voucher.common.utils.SecureUtils;
import io.jsonwebtoken.Claims;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * @coder taoym
 * @datetime 2021/7/7 17:47
 * @desc 系统用户服务
 */
@Service
public class SysUserServiceImpl implements SysUserService {

    @Resource
    private SysUserMapper sysUserMapper;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    private static final BigDecimal RATE_LIMIT_BIG = new BigDecimal("1");
    private static final BigDecimal RATE_LIMIT_SMALL = new BigDecimal("0");

    @Override
    public SysUserLoginVO userLogin(SysUserLoginDTO data) {

        SysUser sysUser = sysUserMapper.selectOne(new QueryWrapper<SysUser>()
                .select("id")
                .eq("username", data.getUsername())
                .eq("password", SecureUtils.encode(data.getPassword())));

        if (ObjectUtils.isEmpty(sysUser)) {
            throw new ExceptionCore(ResponseStatusCode.USER_IS_NOT_EXIST_OR_PASSWORD_IS_WRONG);
        }
        SysUserLoginVO sysUserLoginVO = new SysUserLoginVO();


        Map<String, Object> claims = new HashMap<>(1);
        claims.put("userId", sysUser.getId());
        String token = JwtTokenUtils.createJwtToken(claims, false);
        String refreshToken = JwtTokenUtils.createJwtToken(claims, true);
        sysUserLoginVO.setToken(token);
        sysUserLoginVO.setRefreshToken(refreshToken);
        sysUserLoginVO.setUsername(data.getUsername());

        return sysUserLoginVO;
    }

    @Override
    public Integer updateUser(SysUpdateUserDTO data) {

        redisTemplate.delete(RedisKeyConstant.SYS_USER_INFO);

        Integer userId = AdminThreadLocalUtils.getInstance().get();
        if (new BigDecimal(data.getDistRate()).compareTo(RATE_LIMIT_BIG) > 0 ||
                new BigDecimal(data.getTeamRate()).compareTo(RATE_LIMIT_SMALL) < 0) {
            throw new ExceptionCore(ResponseStatusCode.RATE_IS_WRONG);
        }

        SysUser sysUserExist = sysUserMapper.selectById(userId);

        SysUser sysUser = new SysUser();
        sysUser.setId(userId);
        sysUser.setEmail(data.getEmail());
        sysUser.setApiKey(data.getApiKey());
        sysUser.setPubId(data.getPubId());
        if (!sysUserExist.getAppId().equals(data.getAppId())) {
            sysUser.setAppId(SecureUtils.encode(data.getAppId()));
        }
        if (!sysUserExist.getAppSecret().equals(data.getAppSecret())) {
            sysUser.setAppSecret(SecureUtils.encode(data.getAppSecret()));
        }
        if (!sysUserExist.getPassword().equals(data.getPassword())) {
            sysUser.setPassword(SecureUtils.encode(data.getPassword()));
        }
        sysUser.setDistRate(data.getDistRate());
        sysUser.setTeamRate(data.getTeamRate());

        return sysUserMapper.updateById(sysUser);
    }

    @Override
    public String refreshToken(SysUserRefreshTokenDTO data) {
        Claims claims = JwtTokenUtils.getClaimsFromToken(data.getToken());
        boolean isExpired = JwtTokenUtils.validateTokenIsExpired(data.getRefreshToken(), true);
        if (!isExpired) {
            return JwtTokenUtils.renewalToken(claims);
        }
        return null;
    }

    @Override
    public SysGetUserDetailVO personal() {
        Integer userId = AdminThreadLocalUtils.getInstance().get();

        SysUser sysUser = sysUserMapper.selectById(userId);

        SysGetUserDetailVO sysGetUserDetailVO = new SysGetUserDetailVO();

        sysGetUserDetailVO.setEmail(sysUser.getEmail());
        sysGetUserDetailVO.setUsername(sysUser.getUsername());
        sysGetUserDetailVO.setPassword(sysUser.getPassword());
        sysGetUserDetailVO.setApiKey(sysUser.getApiKey());
        sysGetUserDetailVO.setDistRate(sysUser.getDistRate());
        sysGetUserDetailVO.setTeamRate(sysUser.getTeamRate());
        sysGetUserDetailVO.setId(sysUser.getId());
        sysGetUserDetailVO.setPubId(sysUser.getPubId());
        sysGetUserDetailVO.setAppSecret(sysUser.getAppSecret());
        sysGetUserDetailVO.setAppId(SecureUtils.decrypt(sysUser.getAppId()));

        return sysGetUserDetailVO;
    }
}
